<template>
  <div class="snake-game-container">
    <div class="game-header">
      <h1>贪吃蛇游戏</h1>
      <div class="game-stats">
        <div class="stat-item">
          <span>蛇的长度:</span>
          <span class="stat-value">{{ snake.length }}</span>
        </div>
        <div class="stat-item">
          <span>分数:</span>
          <span class="stat-value">{{ score }}</span>
        </div>
        <div class="stat-item">
          <span>难度:</span>
          <span class="stat-value">{{ difficulty }}</span>
        </div>
      </div>
    </div>
    
    <div class="game-area">
      <canvas 
        ref="gameCanvas" 
        width="500" 
        height="500"
        class="game-canvas"
      ></canvas>
    </div>
    
    <div class="game-controls">
      <select v-model="difficulty" @change="updateDifficulty" class="difficulty-select">
        <option value="easy">简单</option>
        <option value="medium">中等</option>
        <option value="hard">困难</option>
      </select>
      
      <button 
        @click="toggleGame" 
        :class="['control-button', { 'active': isGameRunning }]"
      >
        {{ isGameRunning ? '暂停游戏' : '开始游戏' }}
      </button>
      
      <button 
        @click="resetGame" 
        class="control-button reset-button"
      >
        重新开始
      </button>
    </div>
    
    <div class="game-instructions">
      <p>使用方向键控制蛇的移动，吃掉食物以增长身体。注意避免撞到自己的身体。</p>
    </div>
    
    <div v-if="gameOver" class="game-over-modal">
      <div class="game-over-content">
        <h2>游戏结束！</h2>
        <p>你的分数: {{ score }}</p>
        <p>蛇的长度: {{ snake.length }}</p>
        <button @click="resetGame" class="control-button restart-button">再玩一次</button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue';

// 游戏配置
const gridSize = 20;
const canvasWidth = 500;
const canvasHeight = 500;
const tileCount = canvasWidth / gridSize;

// DOM引用
const gameCanvas = ref(null);

// 游戏状态
const snake = ref([{ x: 12, y: 12 }]);
const food = ref({ x: 5, y: 5 });
const direction = ref('right');
const nextDirection = ref('right');
const score = ref(0);
const isGameRunning = ref(false);
const gameOver = ref(false);
const difficulty = ref('medium');
const difficultySpeeds = { easy: 200, medium: 120, hard: 70 };

// 游戏循环计时器
let gameLoopId = null;
let ctx = null;

// 初始化画布
onMounted(() => {
  if (gameCanvas.value) {
    ctx = gameCanvas.value.getContext('2d');
    initGame();
    drawGame();
  }
  
  // 添加键盘事件监听
  window.addEventListener('keydown', handleKeyDown);
});

// 清理事件监听
onUnmounted(() => {
  window.removeEventListener('keydown', handleKeyDown);
  stopGameLoop();
});

// 初始化游戏
function initGame() {
  snake.value = [{ x: 12, y: 12 }];
  direction.value = 'right';
  nextDirection.value = 'right';
  score.value = 0;
  gameOver.value = false;
  generateFood();
}

// 生成食物
function generateFood() {
  let newFood;
  let foodOnSnake;
  
  do {
    newFood = {
      x: Math.floor(Math.random() * tileCount),
      y: Math.floor(Math.random() * tileCount)
    };
    
    // 检查食物是否在蛇身上
    foodOnSnake = snake.value.some(segment => 
      segment.x === newFood.x && segment.y === newFood.y
    );
  } while (foodOnSnake);
  
  food.value = newFood;
}

// 处理键盘输入
function handleKeyDown(event) {
  const key = event.key;
  
  // 防止在游戏未开始时改变方向
  if (!isGameRunning.value) return;
  
  switch (key) {
    case 'ArrowUp':
      if (direction.value !== 'down') {
        nextDirection.value = 'up';
      }
      break;
    case 'ArrowDown':
      if (direction.value !== 'up') {
        nextDirection.value = 'down';
      }
      break;
    case 'ArrowLeft':
      if (direction.value !== 'right') {
        nextDirection.value = 'left';
      }
      break;
    case 'ArrowRight':
      if (direction.value !== 'left') {
        nextDirection.value = 'right';
      }
      break;
    case ' ': // 空格键暂停/继续
      toggleGame();
      break;
  }
}

// 开始/暂停游戏
function toggleGame() {
  if (isGameRunning.value) {
    stopGameLoop();
  } else {
    if (gameOver.value) {
      initGame();
    }
    startGameLoop();
  }
}

// 开始游戏循环
function startGameLoop() {
  isGameRunning.value = true;
  const speed = difficultySpeeds[difficulty.value];
  
  function loop() {
    if (!isGameRunning.value) return;
    
    // 更新方向
    direction.value = nextDirection.value;
    
    // 移动蛇
    moveSnake();
    
    // 检查碰撞
    if (checkCollision()) {
      endGame();
      return;
    }
    
    // 绘制游戏
    drawGame();
    
    // 继续游戏循环
    gameLoopId = setTimeout(loop, speed);
  }
  
  // 立即执行一次循环
  loop();
}

// 停止游戏循环
function stopGameLoop() {
  isGameRunning.value = false;
  if (gameLoopId) {
    clearTimeout(gameLoopId);
    gameLoopId = null;
  }
}

// 移动蛇
function moveSnake() {
  const head = { ...snake.value[0] };
  
  // 根据方向移动头部
  switch (direction.value) {
    case 'up':
      head.y = (head.y - 1 + tileCount) % tileCount;
      break;
    case 'down':
      head.y = (head.y + 1) % tileCount;
      break;
    case 'left':
      head.x = (head.x - 1 + tileCount) % tileCount;
      break;
    case 'right':
      head.x = (head.x + 1) % tileCount;
      break;
  }
  
  // 将新头部添加到蛇的前面
  snake.value.unshift(head);
  
  // 检查是否吃到食物
  if (head.x === food.value.x && head.y === food.value.y) {
    // 吃到食物，增加分数
    score.value += 10;
    generateFood();
  } else {
    // 没有吃到食物，移除尾部
    snake.value.pop();
  }
}

// 检查碰撞
function checkCollision() {
  const head = snake.value[0];
  
  // 检查是否撞到自己
  for (let i = 1; i < snake.value.length; i++) {
    if (head.x === snake.value[i].x && head.y === snake.value[i].y) {
      return true;
    }
  }
  
  return false;
}

// 结束游戏
function endGame() {
  gameOver.value = true;
  stopGameLoop();
}

// 重置游戏
function resetGame() {
  stopGameLoop();
  initGame();
  drawGame();
}

// 更新难度
function updateDifficulty() {
  if (isGameRunning.value) {
    stopGameLoop();
    startGameLoop();
  }
}

// 绘制游戏
function drawGame() {
  if (!ctx) return;
  
  // 清除画布
  ctx.fillStyle = '#f8f9fa';
  ctx.fillRect(0, 0, canvasWidth, canvasHeight);
  
  // 绘制网格背景
  drawGrid();
  
  // 绘制食物
  drawFood();
  
  // 绘制蛇
  drawSnake();
}

// 绘制网格
function drawGrid() {
  ctx.strokeStyle = '#e9ecef';
  ctx.lineWidth = 0.5;
  
  // 绘制垂直线
  for (let x = 0; x <= canvasWidth; x += gridSize) {
    ctx.beginPath();
    ctx.moveTo(x, 0);
    ctx.lineTo(x, canvasHeight);
    ctx.stroke();
  }
  
  // 绘制水平线
  for (let y = 0; y <= canvasHeight; y += gridSize) {
    ctx.beginPath();
    ctx.moveTo(0, y);
    ctx.lineTo(canvasWidth, y);
    ctx.stroke();
  }
}

// 绘制食物
function drawFood() {
  ctx.fillStyle = '#e74c3c';
  ctx.shadowBlur = 10;
  ctx.shadowColor = '#e74c3c';
  ctx.beginPath();
  ctx.arc(
    food.value.x * gridSize + gridSize / 2,
    food.value.y * gridSize + gridSize / 2,
    gridSize / 2 - 2,
    0,
    Math.PI * 2
  );
  ctx.fill();
  ctx.shadowBlur = 0;
}

// 绘制蛇
function drawSnake() {
  snake.value.forEach((segment, index) => {
    // 为蛇的不同部分设置不同的颜色，创建渐变效果
    if (index === 0) {
      // 蛇头
      drawSnakeHead(segment);
    } else {
      // 蛇身
      ctx.fillStyle = `hsl(120, 70%, ${60 - Math.min(index * 2, 40)}%)`;
      ctx.strokeStyle = '#2c3e50';
      ctx.lineWidth = 1;
      ctx.beginPath();
      ctx.roundRect(
        segment.x * gridSize + 1,
        segment.y * gridSize + 1,
        gridSize - 2,
        gridSize - 2,
        4
      );
      ctx.fill();
      ctx.stroke();
    }
  });
}

// 绘制蛇头
function drawSnakeHead(segment) {
  ctx.fillStyle = '#27ae60';
  ctx.strokeStyle = '#2c3e50';
  ctx.lineWidth = 2;
  
  // 绘制蛇头主体
  ctx.beginPath();
  ctx.roundRect(
    segment.x * gridSize + 1,
    segment.y * gridSize + 1,
    gridSize - 2,
    gridSize - 2,
    6
  );
  ctx.fill();
  ctx.stroke();
  
  // 根据方向绘制眼睛
  drawEyes(segment);
}

// 绘制蛇的眼睛
function drawEyes(segment) {
  const eyeSize = gridSize / 6;
  const eyeOffset = gridSize / 4;
  
  ctx.fillStyle = '#fff';
  
  switch (direction.value) {
    case 'up':
      // 上眼睛
      ctx.beginPath();
      ctx.arc(
        segment.x * gridSize + eyeOffset,
        segment.y * gridSize + eyeOffset,
        eyeSize,
        0,
        Math.PI * 2
      );
      ctx.arc(
        segment.x * gridSize + gridSize - eyeOffset,
        segment.y * gridSize + eyeOffset,
        eyeSize,
        0,
        Math.PI * 2
      );
      ctx.fill();
      break;
    case 'down':
      // 下眼睛
      ctx.beginPath();
      ctx.arc(
        segment.x * gridSize + eyeOffset,
        segment.y * gridSize + gridSize - eyeOffset,
        eyeSize,
        0,
        Math.PI * 2
      );
      ctx.arc(
        segment.x * gridSize + gridSize - eyeOffset,
        segment.y * gridSize + gridSize - eyeOffset,
        eyeSize,
        0,
        Math.PI * 2
      );
      ctx.fill();
      break;
    case 'left':
      // 左眼睛
      ctx.beginPath();
      ctx.arc(
        segment.x * gridSize + eyeOffset,
        segment.y * gridSize + eyeOffset,
        eyeSize,
        0,
        Math.PI * 2
      );
      ctx.arc(
        segment.x * gridSize + eyeOffset,
        segment.y * gridSize + gridSize - eyeOffset,
        eyeSize,
        0,
        Math.PI * 2
      );
      ctx.fill();
      break;
    case 'right':
      // 右眼睛
      ctx.beginPath();
      ctx.arc(
        segment.x * gridSize + gridSize - eyeOffset,
        segment.y * gridSize + eyeOffset,
        eyeSize,
        0,
        Math.PI * 2
      );
      ctx.arc(
        segment.x * gridSize + gridSize - eyeOffset,
        segment.y * gridSize + gridSize - eyeOffset,
        eyeSize,
        0,
        Math.PI * 2
      );
      ctx.fill();
      break;
  }
}

// 监听游戏状态变化，重绘游戏
watch([snake, food, isGameRunning], () => {
  if (!isGameRunning.value) {
    drawGame();
  }
});
</script>

<style scoped>
.snake-game-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px;
  min-height: 100vh;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: #2c3e50;
}

.game-header {
  text-align: center;
  margin-bottom: 20px;
  background: rgba(255, 255, 255, 0.95);
  padding: 20px 40px;
  border-radius: 15px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(10px);
}

.game-header h1 {
  margin: 0 0 15px 0;
  font-size: 2.5rem;
  background: linear-gradient(45deg, #27ae60, #2ecc71);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-weight: bold;
}

.game-stats {
  display: flex;
  justify-content: center;
  gap: 30px;
  flex-wrap: wrap;
}

.stat-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-size: 1.1rem;
}

.stat-value {
  font-size: 1.4rem;
  font-weight: bold;
  color: #27ae60;
  margin-top: 5px;
}

.game-area {
  background: rgba(255, 255, 255, 0.95);
  padding: 20px;
  border-radius: 15px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(10px);
  margin-bottom: 20px;
}

.game-canvas {
  border: 2px solid #34495e;
  border-radius: 8px;
  background: #f8f9fa;
}

.game-controls {
  display: flex;
  gap: 15px;
  margin-bottom: 20px;
  flex-wrap: wrap;
  justify-content: center;
}

.difficulty-select,
.control-button {
  padding: 12px 24px;
  font-size: 1rem;
  border: none;
  border-radius: 25px;
  cursor: pointer;
  transition: all 0.3s ease;
  font-weight: 600;
}

.difficulty-select {
  background: rgba(255, 255, 255, 0.9);
  border: 2px solid #34495e;
  color: #2c3e50;
  outline: none;
}

.control-button {
  background: linear-gradient(45deg, #3498db, #2980b9);
  color: white;
  box-shadow: 0 4px 15px rgba(52, 152, 219, 0.3);
}

.control-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(52, 152, 219, 0.4);
}

.control-button:active {
  transform: translateY(0);
}

.control-button.active {
  background: linear-gradient(45deg, #e74c3c, #c0392b);
  box-shadow: 0 4px 15px rgba(231, 76, 60, 0.3);
}

.reset-button {
  background: linear-gradient(45deg, #9b59b6, #8e44ad);
}

.reset-button:hover {
  box-shadow: 0 6px 20px rgba(155, 89, 182, 0.4);
}

.game-instructions {
  background: rgba(255, 255, 255, 0.9);
  padding: 15px 30px;
  border-radius: 10px;
  text-align: center;
  max-width: 500px;
  margin-bottom: 20px;
}

.game-instructions p {
  margin: 0;
  font-size: 1rem;
  line-height: 1.6;
  color: #34495e;
}

.game-over-modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
  animation: fadeIn 0.3s ease;
}

.game-over-content {
  background: white;
  padding: 40px;
  border-radius: 15px;
  text-align: center;
  box-shadow: 0 10px 50px rgba(0, 0, 0, 0.3);
  animation: slideIn 0.3s ease;
}

.game-over-content h2 {
  margin: 0 0 20px 0;
  font-size: 2rem;
  color: #e74c3c;
}

.game-over-content p {
  margin: 10px 0;
  font-size: 1.2rem;
  color: #2c3e50;
}

.restart-button {
  margin-top: 20px;
  padding: 15px 40px;
  font-size: 1.1rem;
  background: linear-gradient(45deg, #27ae60, #2ecc71);
}

.restart-button:hover {
  box-shadow: 0 6px 20px rgba(39, 174, 96, 0.4);
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes slideIn {
  from {
    transform: translateY(-50px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

/* 响应式设计 */
@media (max-width: 600px) {
  .snake-game-container {
    padding: 10px;
  }
  
  .game-header {
    padding: 15px 20px;
  }
  
  .game-header h1 {
    font-size: 2rem;
  }
  
  .game-stats {
    gap: 15px;
  }
  
  .stat-item {
    font-size: 1rem;
  }
  
  .stat-value {
    font-size: 1.2rem;
  }
  
  .game-area {
    padding: 10px;
  }
  
  .game-canvas {
    max-width: 100%;
    height: auto;
  }
  
  .game-controls {
    flex-direction: column;
    align-items: center;
  }
  
  .difficulty-select,
  .control-button {
    width: 200px;
  }
}
</style>